package mx.com.asteca.vista;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.model.SelectItem;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import mx.com.asteca.comun.Constantes;
import mx.com.asteca.comun.dto.AlumnoDocumentoDTO;
import mx.com.asteca.comun.dto.DocumentoDTO;
import mx.com.asteca.comun.dto.EstatusDTO;
import mx.com.asteca.comun.dto.InstructorDocumentoDTO;
import mx.com.asteca.comun.dto.PersonaDTO;
import mx.com.asteca.fachada.AlumnoFachada;
import mx.com.asteca.fachada.FachadaException;
import mx.com.asteca.fachada.InstructorFachada;
import mx.com.asteca.fachada.PersonaFachada;
import mx.com.asteca.util.RandomString;

import org.primefaces.context.RequestContext;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.DashboardColumn;
import org.primefaces.model.DashboardModel;
import org.primefaces.model.DefaultDashboardColumn;
import org.primefaces.model.DefaultDashboardModel;
import org.springframework.util.CollectionUtils;

@ManagedBean(name = Constantes.BEAN_DASHBOARD)
@ViewScoped
public class DashboardControlador extends BaseController implements
		Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private DashboardModel model;
	@ManagedProperty("#{personaFachadaImpl}")
	private transient PersonaFachada fachadaPersona;
	@ManagedProperty("#{instructorFachadaImpl}")
	private transient InstructorFachada fachadaInstructor;
	@ManagedProperty("#{alumnoFachadaImpl}")
	private transient AlumnoFachada fachadaAlumno;
	private List<EstatusDTO> listEstatus;
	private String nombre;
	private String nombreRol;
	private List<DocumentoDTO> listaDocs;
	private List<DocumentoDTO> listaNuevosDocs;
	private boolean activeDocumentos;
	private PersonaDTO dtoPersona;
	private DocumentoDTO itemSelected;
	private String nuevoDocRuta;
	private String nuevoDocNombre;
	private int idAlumno;
	private int idInstructor;
	private Short idEstatus;
	private List<SelectItem> listSelectItemsEstatus;
	
	
	@PostConstruct
	public void populate() {
		try {
			setUsuario();
		} catch (FachadaException e) {
			super.addErrorMessage(Constantes.MESSAGE_TITLE_ERROR, Constantes.ERROR_OBTENIENDO_LISTA_CATALOGO);
		}
		model = new DefaultDashboardModel();
		DashboardColumn column1 = new DefaultDashboardColumn();
		column1.addWidget("board1");
		DashboardColumn column2 = new DefaultDashboardColumn();
		column2.addWidget("board2");
		model.addColumn(column1);
		model.addColumn(column2);
	}

	@Override
	String getModulo() {
		return null;
	}

	private void initListaSelectEstatus(){
		if(CollectionUtils.isEmpty(listSelectItemsEstatus)){
			listSelectItemsEstatus = new ArrayList<SelectItem>();
			for(EstatusDTO dto : getListEstatus()){
				SelectItem item = new SelectItem(dto.getIdEstatus(), dto.getDescEstatus());
				listSelectItemsEstatus.add(item);
			}
		}
	}
	
	private void initListEstatus(){
		if(CollectionUtils.isEmpty(listEstatus)){
			try {
				listEstatus = fachadaAlumno.getEstatus();
			} catch (FachadaException e) {
				super.addErrorMessage(Constantes.MESSAGE_TITLE_ERROR, Constantes.ERROR_OBTENIENDO_LISTA_CATALOGO);
			}
		}
	}
	
	public void setUsuario() throws FachadaException {
		HttpServletRequest servletReq = (HttpServletRequest) super
				.getFacesContext().getCurrentInstance().getExternalContext()
				.getRequest();
		HttpSession session = servletReq.getSession();
		int idPersona = (Integer) session.getAttribute(Constantes.SESION_ATT_ID_USUARIO);
		dtoPersona = fachadaPersona.findByPK(idPersona);
		nombre = dtoPersona.getNombre() + " " + dtoPersona.getApellidoP() + " " + dtoPersona.getApellidoM();
		if(fachadaPersona.isAdmin(idPersona)){
			nombreRol = "Administrativo";
		}else if(fachadaPersona.isAlumno(idPersona)){
			nombreRol = "Alumno";
			idAlumno = fachadaPersona.getIdAlumno(idPersona);
			activeDocumentos = true;
			listaDocs = fachadaPersona.getDocumentosByAlumno(idPersona);
			if(CollectionUtils.isEmpty(listaDocs)){
				listaDocs = new ArrayList<DocumentoDTO>();
			}
		}else if(fachadaPersona.isInstructor(idPersona)){
			nombreRol = "Instructor";
			idInstructor = fachadaPersona.getIdInstructor(idPersona);
			activeDocumentos = true;
			listaDocs = fachadaPersona.getDocumentosByInstructor(idPersona);
			if(CollectionUtils.isEmpty(listaDocs)){
				listaDocs = new ArrayList<DocumentoDTO>();
			}
		}
	}
	
	public void addNuevoDocumento() throws FachadaException {
		if(idEstatus == null || idEstatus.shortValue() == 0){
			super.addWarningMessage(Constantes.WARNING_NECESITAS_LLENAR_CAMPOS_REQUERIDOS);
			return;
		}
		DocumentoDTO documentoDTO = new DocumentoDTO();
		documentoDTO.setIdEstatus(idEstatus);//TODO poner un estatus de subido desde el dashboard
		documentoDTO.setNombre(nuevoDocNombre);
		documentoDTO.setRuta(nuevoDocRuta);
		if (CollectionUtils.isEmpty(listaNuevosDocs)) {
			listaNuevosDocs = new ArrayList<DocumentoDTO>();
		}
		listaNuevosDocs.add(documentoDTO);
	}
	
	public void save(){
		if(idEstatus == null || idEstatus.shortValue() == 0){
			super.addWarningMessage(Constantes.WARNING_NECESITAS_LLENAR_CAMPOS_REQUERIDOS);
			return;
		}
		if(nombreRol.equals("Alumno")){
			for(DocumentoDTO doc : listaNuevosDocs){
				AlumnoDocumentoDTO docDto = new AlumnoDocumentoDTO();
				docDto.setDocumento(doc);
				docDto.setIdAlumno(idAlumno);
				try {
					fachadaAlumno.saveDocumentoPorAlumno(docDto);
					listaDocs.add(doc);
					RequestContext.getCurrentInstance().execute("nuevoDialog.hide()");
					super.addInfoMessage(Constantes.MESSAGE_TITLE_INFO, Constantes.NUEVO_REGISTRO_EXITOSO);
					addBitacora(Constantes.ACCION_NUEVO_REGISTRO, Constantes.ACCION_NUEVO_REGISTRO_EXITOSO_MENSAJE+":Doc de Instructor "+doc.getNombre()+":");
				} catch (FachadaException e) {
					super.addErrorMessage(Constantes.ERROR_SUBIDA_ARCHIVO);
					RequestContext.getCurrentInstance().execute("nuevoDialog.hide()");
					addBitacora(Constantes.ACCION_NUEVO_REGISTRO, Constantes.ACCION_NUEVO_REGISTRO_FALLIDO_MENSAJE+":Doc de Instructor "+doc.getNombre()+":");
				}
			}
		}else if(nombreRol.equals("Instructor")){
			for(DocumentoDTO doc : listaNuevosDocs){
				InstructorDocumentoDTO docDTO = new InstructorDocumentoDTO();
				docDTO.setDocumento(doc);
				docDTO.setIdInstructor(idInstructor);
				try {
					fachadaInstructor.saveInstructorDocumento_Dashboard(docDTO);
					listaDocs.add(doc);
					RequestContext.getCurrentInstance().execute("nuevoDialog.hide()");
					super.addInfoMessage(Constantes.MESSAGE_TITLE_INFO, Constantes.NUEVO_REGISTRO_EXITOSO);
					addBitacora(Constantes.ACCION_NUEVO_REGISTRO, Constantes.ACCION_NUEVO_REGISTRO_EXITOSO_MENSAJE+":Doc de Alumno "+doc.getNombre()+":");
				} catch (FachadaException e) {
					super.addErrorMessage(Constantes.ERROR_SUBIDA_ARCHIVO);
					RequestContext.getCurrentInstance().execute("nuevoDialog.hide()");
					addBitacora(Constantes.ACCION_NUEVO_REGISTRO, Constantes.ACCION_NUEVO_REGISTRO_FALLIDO_MENSAJE+":Doc de Alumno "+doc.getNombre()+":");
				}
			}
		}
	}
	
	public void update(){
		
	}
	
	public void saveCancel(){
		listaNuevosDocs = new ArrayList<DocumentoDTO>();
	}
	
	public void delete(){
	}
	
	public void cancelDelete(){
		
	}
	
	public void handlerNuevoFileUpload(FileUploadEvent event) {
		try {
			String ruta = fachadaInstructor.getRuta();
			File targetFolder = new File(ruta);
			String prefijo = RandomString.getRandomString();
			String fileName = prefijo + "_" + event.getFile().getFileName();
			InputStream inputStream = event.getFile().getInputstream();
			OutputStream out = new FileOutputStream(new File(targetFolder,
					fileName));
			nuevoDocRuta = targetFolder.getAbsolutePath()
					+ targetFolder.separator +fileName;
			nuevoDocNombre = event.getFile().getFileName();
			int read = 0;
			byte[] bytes = new byte[1024];

			while ((read = inputStream.read(bytes)) != -1) {
				out.write(bytes, 0, read);
			}
			inputStream.close();
			out.flush();
			out.close();
			addNuevoDocumento();			
		} catch (IOException e) {
			super.addErrorMessage(Constantes.ERROR_SUBIDA_ARCHIVO);
		} catch (FachadaException e) {
			super.addErrorMessage(Constantes.ERROR_SUBIDA_ARCHIVO);
		}
	}

	
	
	/**
	 * @return the model
	 */
	public DashboardModel getModel() {
		return model;
	}

	
	
	/**
	 * @param model
	 *            the model to set
	 */
	public void setModel(DashboardModel model) {
		this.model = model;
	}

	/**
	 * @return the fachadaPersona
	 */
	public PersonaFachada getFachadaPersona() {
		return fachadaPersona;
	}

	/**
	 * @param fachadaPersona the fachadaPersona to set
	 */
	public void setFachadaPersona(PersonaFachada fachadaPersona) {
		this.fachadaPersona = fachadaPersona;
	}

	/**
	 * @return the nombre
	 */
	public String getNombre() {
		return nombre;
	}

	/**
	 * @param nombre the nombre to set
	 */
	public void setNombre(String nombre) {
		this.nombre = nombre;
	}

	/**
	 * @return the nombreRol
	 */
	public String getNombreRol() {
		return nombreRol;
	}

	/**
	 * @param nombreRol the nombreRol to set
	 */
	public void setNombreRol(String nombreRol) {
		this.nombreRol = nombreRol;
	}

	/**
	 * @return the listaDocs
	 */
	public List<DocumentoDTO> getListaDocs() {
		return listaDocs;
	}

	/**
	 * @param listaDocs the listaDocs to set
	 */
	public void setListaDocs(List<DocumentoDTO> listaDocs) {
		this.listaDocs = listaDocs;
	}

	/**
	 * @return the activeDocumentos
	 */
	public boolean isActiveDocumentos() {
		return activeDocumentos;
	}

	/**
	 * @param activeDocumentos the activeDocumentos to set
	 */
	public void setActiveDocumentos(boolean activeDocumentos) {
		this.activeDocumentos = activeDocumentos;
	}

	/**
	 * @return the dtoPersona
	 */
	public PersonaDTO getDtoPersona() {
		return dtoPersona;
	}

	/**
	 * @param dtoPersona the dtoPersona to set
	 */
	public void setDtoPersona(PersonaDTO dtoPersona) {
		this.dtoPersona = dtoPersona;
	}

	/**
	 * @return the itemSelected
	 */
	public DocumentoDTO getItemSelected() {
		return itemSelected;
	}

	/**
	 * @param itemSelected the itemSelected to set
	 */
	public void setItemSelected(DocumentoDTO itemSelected) {
		this.itemSelected = itemSelected;
	}

	/**
	 * @return the listaNuevosDocs
	 */
	public List<DocumentoDTO> getListaNuevosDocs() {
		return listaNuevosDocs;
	}

	/**
	 * @param listaNuevosDocs the listaNuevosDocs to set
	 */
	public void setListaNuevosDocs(List<DocumentoDTO> listaNuevosDocs) {
		this.listaNuevosDocs = listaNuevosDocs;
	}

	/**
	 * @return the fachadaInstructor
	 */
	public InstructorFachada getFachadaInstructor() {
		return fachadaInstructor;
	}

	/**
	 * @param fachadaInstructor the fachadaInstructor to set
	 */
	public void setFachadaInstructor(InstructorFachada fachadaInstructor) {
		this.fachadaInstructor = fachadaInstructor;
	}

	/**
	 * @return the nuevoDocRuta
	 */
	public String getNuevoDocRuta() {
		return nuevoDocRuta;
	}

	/**
	 * @param nuevoDocRuta the nuevoDocRuta to set
	 */
	public void setNuevoDocRuta(String nuevoDocRuta) {
		this.nuevoDocRuta = nuevoDocRuta;
	}

	/**
	 * @return the nuevoDocNombre
	 */
	public String getNuevoDocNombre() {
		return nuevoDocNombre;
	}

	/**
	 * @param nuevoDocNombre the nuevoDocNombre to set
	 */
	public void setNuevoDocNombre(String nuevoDocNombre) {
		this.nuevoDocNombre = nuevoDocNombre;
	}

	/**
	 * @return the fachadaAlumno
	 */
	public AlumnoFachada getFachadaAlumno() {
		return fachadaAlumno;
	}

	/**
	 * @param fachadaAlumno the fachadaAlumno to set
	 */
	public void setFachadaAlumno(AlumnoFachada fachadaAlumno) {
		this.fachadaAlumno = fachadaAlumno;
	}

	/**
	 * @return the idAlumno
	 */
	public int getIdAlumno() {
		return idAlumno;
	}

	/**
	 * @param idAlumno the idAlumno to set
	 */
	public void setIdAlumno(int idAlumno) {
		this.idAlumno = idAlumno;
	}

	/**
	 * @return the idInstructor
	 */
	public int getIdInstructor() {
		return idInstructor;
	}

	/**
	 * @param idInstructor the idInstructor to set
	 */
	public void setIdInstructor(int idInstructor) {
		this.idInstructor = idInstructor;
	}

	/**
	 * @return the listEstatus
	 */
	public List<EstatusDTO> getListEstatus() {
		initListEstatus();
		return listEstatus;
	}

	/**
	 * @param listEstatus the listEstatus to set
	 */
	public void setListEstatus(List<EstatusDTO> listEstatus) {
		this.listEstatus = listEstatus;
	}

	/**
	 * @return the idEstatus
	 */
	public Short getIdEstatus() {
		return idEstatus;
	}

	/**
	 * @param idEstatus the idEstatus to set
	 */
	public void setIdEstatus(Short idEstatus) {
		this.idEstatus = idEstatus;
	}

	/**
	 * @return the listSelectItemsEstatus
	 */
	public List<SelectItem> getListSelectItemsEstatus() {
		initListaSelectEstatus();
		return listSelectItemsEstatus;
	}

	/**
	 * @param listSelectItemsEstatus the listSelectItemsEstatus to set
	 */
	public void setListSelectItemsEstatus(List<SelectItem> listSelectItemsEstatus) {
		this.listSelectItemsEstatus = listSelectItemsEstatus;
	}

}
